home *** CD-ROM | disk | FTP | other *** search
- Path: newshost.lanl.gov!tanmoy
- From: tanmoy@qcd.lanl.gov (Tanmoy Bhattacharya)
- Newsgroups: comp.lang.c
- Subject: Re: Problem with c code, please help!
- Date: 19 Jan 1996 16:27:32 GMT
- Organization: Los Alamos National Laboratory
- Message-ID: <TANMOY.96Jan19092732@qcd.lanl.gov>
- References: <surgsw-1901960148530001@128.206.206.86>
- <mikedorman-1901960725380001@205.148.200.150>
- NNTP-Posting-Host: qcd.lanl.gov
- Mime-Version: 1.0
- Content-Type: text
- In-reply-to: mikedorman@cedarnet.com's message of Fri, 19 Jan 1996 07:25:37 -0600
-
- --text follows this line--
- I try to avoid posting in a hurry ... but this post needs to be responded to.
-
- In article <mikedorman-1901960725380001@205.148.200.150>
- mikedorman@cedarnet.com (Mike Dorman) writes:
- <snip>
- > I have been trying to get this very simple piece of code to work for
- > hours. What is the problem???????
- >
- > #include <stdio.h>
- >
- > main()
- > {
- > int i=0;
- > char word[100], c;
-
- word is an array of 100 chars, there are no pointers declared here.
- change word to this:
- char *word;
- and it will be *much* easier.
-
- Please do _not_ do that! Never use a pointer where an array will do.
- 1) Arrays will typically be optimized far better by the compiler
- because it does not have to check for aliasing. In this
- particular context, a good compiler _could_ have assumed
- `noalias' anyway: but not all compilers are that good.
- 2) Pointers are more `powerful' than arrays: and hence can cause
- more subtle errors than arrays.
- 3) Pointers need to point to allocated memory: a point which the
- poster seems to have completely missed. A pointer cannot be used
- without making it point somewhere.
-
- > printf("Enter a word: ");
- > while( (c = getchar()) != '\n') {
-
- This statement is dangerous: you are not testing to see if input is
- exhausted before the line has ended. Such things can happen.
-
- > *word = c;
- here, replace *word (which is a pointer to something...you didn't specify
- which char in word you wanted it to point to, so it could be pointing to
- just about anything) with
-
- void flame() {
-
- Please do not respond if you do not know C. Some may say that you
- learn by making mistakes ... if you want to do that please make
- absolutely clear that you have no knowledge of C and are trying to
- learn by throwing around random ideas. _My_ time is wasted responding
- to this post, in case the original poster perchance believes you
- (Sorry, original poster; beginners will often believe _anything_). I
- do not appreciate that; and hence would suggest that you learn the
- basics by the more conventional means.
-
- }
-
- *word is _not_ a pointer. * means take the object that it points
- to. word is an array, which when used in expressions (other than as an
- operand of & or sizeof) decays to a pointer to the _first_ element of
- the array. Note that there is no ambiguity about which character of
- the word is meant. *word itself is that character, not a pointer.
-
- strcat(word, *c);
-
- And if word were pointng nowhere, did you think that strcat would
- magically make it point somewhere?
-
- Actually what the original poster wanted could be most succinctly
- written as word[i++] = c. (Assuming a int i=0 at the top) This is a
- statement that sets the ith element (counting 0th element, 1st element
- etc.) of word to c, and increments i in preparation for the next
- store. Of course, the loop should check that i < sizeof word. (or, rather,
- sizeof word - 1 to save space for the closing null character).
-
- which will copy c onto the end of word, adding the character to word.
- > word == word + 1;
- you don't need this...just get rid of it.
-
- == is the comparison operator, not the assignment operator. In this
- you are comparing whether a pointer to the first character of word is
- the same as the one to the second, and doing nothing with the result.
-
- Remember that word is an array, only in contexts where a _value_ is
- needed, a pointer to the first character is taken to be its value. One
- can change a pointer variable to point to some other place, one
- obviously cannot change a value! (A related example is that you can
- say i = 6, but i+0 = 6 is not valid.)
-
- If word were a pointer pointing somewhere valid, then both word++ and
- word = word + 1 would have worked. Thus instead of the int i = 0
- method suggested above, you can use char *ptr = word, and then instead
- of writing word[i++] = c, you can write *ptr++ = c, and instead of
- checking i < sizeof word - 1, you can check ptr < &word[sizeof word -
- 1].
-
- > }
- > printf("You entered: ");
- > *word = 0;
-
- A stylistic issue: interchange the above two lines. *word=0 (or the
- valid replacement *ptr = 0 or word[i] = 0 depending on the method
- chosen) has presumably nothing to do with your writing out the stuff,
- but more to do with reading in the stuff and making it into a valid
- `string'. As such, it should come closer to the block reading in the
- stuff, than writing it out. (Of course, if you consider adding the 0
- to be a hack designed at writing the stuff out easily, it is different
- matter.)
-
- > while( *word != '\n' )
-
- Now I do not follow your logic. If you thought that word has been
- changing all the while, then word is already at the end of everything,
- how did you think of getting to the characters stored in the array
- (which are before word) by incrementing word?
-
- There is a slight possiblity that you thought *word=0 puts word back
- to the beginning of the characters that you stored. (That would
- explain the placement of the statement.) Unfortunately, it does
- nothing of that sort: there is nothing which keeps track of where your
- pointer pointed at the beginning. *word=0 just sets the character that
- word is pointing at to be zero. This is the conventional way of
- representing the spot where a character string ends ... so that
- a pointer can step through the word and always figure out whether it
- has reached the end. (Of course, this method does not work if you are
- trying to store real 0's in the word: but that is rare.)
-
- Second, if you look carefully at the readin loop above, I think that
- you did not actually store the '\n'. So how do you expect to find it
- now?
-
- What you probably wanted was
-
- for (i = 0; word[i] != 0; i++) {
-
- or
-
- for (ptr = word; *ptr != 0; ptr++) {
-
- Note that in both cases, either i or ptr is set back to its initial
- value by the programmer: the programmer has to remember what the
- initial value was. This is the reason why even if word++ were allowed
- to change word, it would not have been the best thing to use here.
-
- > {
- > putchar( *word );
- > word == word + 1;
- > }
-
- I hope you can correct this loop now. Note also that whether you
- stored the '\n' or not, it is always a good idea to write out a
- '\n'. I do not like to use programs which needlessly leave incomplete
- output lines.
-
- Just get rid of that whole while loop, and replace it with:
- puts(word);
-
- > }
- >
- > I think the problem I am having is due to my not knowing when to use the
- > '*' operator. When do you use it? Also, why won't my goddam compiler let
-
- Ok, one problem at a time...
-
- When you say "char word[100]", that defines a object (and object it
- anything in memory) called word, that contains 100 chars (or 100 byte
- values). So, later when word is referenced (like any array) you need to
- tell the compiler which value in the array you want by adding brackets to
- the end (so, if you wanted the first char in word, you'd say word[0])
- (arrays are referenced from *ZERO* so array[0] is really the first value
- in the array).
-
- correct. It is usually called the first element, because the word
- `value' is reserved to contrast against an `lvalue' or an
- `object'. array[0] is an lvalue (which means it is an object) which
- can usually be assigned to, taken the address of, etc. (unless
- prohibited by some other rule.)
-
- When you use the * operator, that returns a pointer to something. So
-
- operators never `return' anything. only functions `return'
- something. operators operate on operands and produce lvalues or
- (r)values as the situation demands.
-
- * operates on a pointer.
-
- *word returns a pointer to word, an array of chars. I'm not sure how
-
- *word is an lvalue which is exactly the same object that word points
- to.
-
- standard C deals with this, but i would recommend not doing it that way.
- If you needed a pointer to a string from a char array (which is kindof
- what you need, sortof) you'd get one by getting a pointer to the first
- char (*word[0]).
-
- Here I am totally lost (or rather, given that you did not actually ask
- any question: you assumed you knew; I do not want to take the time off
- to figure out all your misconceptions.
-
- Also, when getting string information from the user, you probably
- shouldn't use a char array (I know it seems to make more sense that way,
- but soon it'll become clear that it doesn't), but you should use a string
- pointer, like this:
- char *word;
- Now, word is a pointer to a string, which has no specific or limited
- length. Then you can use the standard functions like strcpy and strcat to
- work on string pointers.
-
- Bogus and dangerous advice from someone who will suffer trying to
- write correct C programs, unless remedial measures are taken immediately.
-
- To do it with an array, you need another variable to keep track of how
- many characters you've already put into word, so you can index the array
- correctly:
-
-
-
- main()
- {
- char word[100], c;
- int i;
- i = 0;
-
- puts("Enter a word:");
- while((c = getch()) != \n)
- {
- word[i] = c;
- i++;
- }
-
- puts("You entered: ");
- puts(*word[0]);
-
- Did you try to compile this? Did your compiler make sense of this
- line? This is comp.lang.c, not comp.lang.garbage.
-
- In any case, how did you expect puts to know where the string ends?
-
- }
-
- But, if you did it with a string pointer, it's this much easier:
-
- main()
- {
- char *word;
-
- puts("Enter a word: ");
- while(scanf("%s", word) != 0)
-
- puts("You entered: ");
- puts(word);
- }
-
- God! If thou exist, save this newsgroup from such absolute
- idiocies. Where do you think scanf writes the word in to? Where does
- word point? Didn't you even stop to think once that a pointer needs to
- `point' somewhere?
-
- > me do word++; instead of word == word +1; I also tried to do *word++;
- > and it didn't work, what is the deal with that. It won't let me put word
- > = word + 1;. It insists on the double ='s. Why is that?
-
- Are you *SURE*?? There is a difference between = and == in C. = is
- actually the assignment operator (ie: in a = b, a is assigned the value of
- b). == is the equality test operator (ie: 1 == 1 returns TRUE (1) ). So,
- word == word + 1 would alwas return false. You should be able to do
- word++ (although probably the reason why you couldn't here was because
- word was an array of chars and the compiler didn't know what to do with
- word, it would've been ok if you did word[0]++, but you wouldn't have
- needed it anyway.
-
- > ps: is there a way to find out what exactly error messages mean? I kept
- > getting something similar to: not an Ivalue. It would be nice if I knew
- > what the hell that meant.
-
- An lvalue is a value that can be assigned to. For instance, if you had 3
- = b + 2, the compiler would complain about the 3 because you can't store
- another value to 3. It probably complained about word = word + 1 because
- word is a "constant" that defines the beggining of the char array. I
- don't really know what you get from "word" if you have a "char word[100]"
- array, except something really wierd, so you probably shouldn't use it.
-
- You would have known what `you get from word' and have used it
- happily, if you just bothered to look at the FAQ before posting. Most
- FAQs are available from rtfm.mit.edu
-
- Well, there it is! Hope that helps! Feel free to email me if you have
- other problems.
-
- Such absolutely incorrect advice hardly ever helps.
-
- Cheers
- Tanmoy
- --
- tanmoy@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tanmoy@lanl.gov"(1.218=1242)
- Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
- Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
- <http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
- internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
- fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]
-